package com.stylefeng.guns.core.util;

import com.google.gson.Gson;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.exception.GunsExceptionEnum;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created with IntelliJ IDEA.
 *
 * @author: wangxindong
 * @date: 2018/4/1-12:00
 */
public class Base64Util {

    // ================================================================
    // Constants
    // ================================================================

    private static final Logger LOGGER = LoggerFactory.getLogger(Base64Util.class);

    // ================================================================
    // Fields
    // ================================================================

    private static final Gson GSON = new Gson();


    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * Base64加密（UTF-8）
     *
     * @param data
     * @return
     */
    public static String encode(String data) throws GunsException {
        return encode(data, "utf-8");
    }

    /**
     * Base64加密（UTF-8）
     *
     * @param data
     * @return
     */
    public static String encode(Object data) throws GunsException {
        String dataJson = GSON.toJson(data);
        return encode(dataJson, "utf-8");
    }

    /**
     * Base64加密
     *
     * @param data
     * @param charset
     * @return
     */
    public static String encode(String data, String charset) throws GunsException {
        try {
            byte[] b = encode(data.getBytes(charset));
            return new String(b, charset);
        } catch (Exception ex) {
            LOGGER.error(ex.toString());
            throw new GunsException(GunsExceptionEnum.BASE64_CODER_ERROR);
        }
    }

    /**
     * Base64加密
     *
     * @param data
     * @return
     */
    public static byte[] encode(byte[] data) {
        return Base64.encodeBase64(data);
    }

    /**
     * Base64解密(UTF-8)
     *
     * @param data
     * @return
     */
    public static String decode(String data) throws GunsException {
        return decode(data, "utf-8");
    }

    /**
     * Base64解密(UTF-8)
     *
     * @param data
     * @return
     */
    public static <T> T decode(String data, Class<T> clazz) throws GunsException {
        String dataJson = decode(data, "utf-8");
        return GSON.fromJson(dataJson, clazz);
    }

    /**
     * Base64解密
     *
     * @param data
     * @param charset 编码格式
     * @return
     */
    public static String decode(String data, String charset) throws GunsException {
        try {
            byte[] b = decode(data.getBytes(charset));
            return new String(b, charset);
        } catch (Exception ex) {
            LOGGER.error(ex.toString());
            throw new GunsException(GunsExceptionEnum.BASE64_CODER_ERROR);
        }
    }

    /**
     * Base64解密
     *
     * @param data
     * @return
     */
    public static byte[] decode(byte[] data) {
        return Base64.decodeBase64(data);
    }


    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================


    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
